﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using Coding4Fun.Kinect.Wpf;
using System.Runtime.InteropServices;

namespace newVersionKinect
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        [DllImport("writevideo.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern int fnInitVideo(string name, int fcc, double fps, int w, int h);
        [DllImport("writevideo.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern int fnWriteVideo(byte[] data, int bytePerPixel);
        [DllImport("writevideo.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern void fnKeepData(short[] data, int bytePerPixel);
        [DllImport("writevideo.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern void fnCloseVideo();

        public MainWindow()
        {
//             InitializeComponent();
        }

        private void writeColorFrame()
        {
//             int stride = colorImg.PixelWidth * colorImg.Format.BitsPerPixel / 8;
//             byte[] data = new byte[colorImg.PixelHeight * stride];
//             colorImg.CopyPixels(data, stride, 0);
            fnWriteVideo(colorPixels, 4);
        }

        private void writeDepthFrame()
        {
            fnKeepData(pixels, 1);
        }


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            kinectSensorChooser1.KinectSensorChanged += new DependencyPropertyChangedEventHandler(kinectSensorChooser1_KinectSensorChanged);
//             if (KinectSensor.KinectSensors.Count > 0)
//             {
//                 _sensor = KinectSensor.KinectSensors[0];
//                 if (_sensor.Status == KinectStatus.Connected)
//                 {
//                     _sensor.ColorStream.Enable();
//                     _sensor.DepthStream.Enable();
//                     _sensor.SkeletonStream.Enable();
//                     _sensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(_sensor_AllFramesReady);
//                     _sensor.Start();
//                 }
//             }

        }

        void kinectSensorChooser1_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            KinectSensor oldSensor = (KinectSensor)e.OldValue;
            StopKinect(oldSensor);
            KinectSensor newSensor = (KinectSensor)e.NewValue;

            newSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
//             newSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
            fnInitVideo("none sense", -1, 30, 640, 480);
            newSensor.DepthStream.Range = DepthRange.Near;
            newSensor.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(newSensor_DepthFrameReady);
//             newSensor.ColorFrameReady +=new EventHandler<ColorImageFrameReadyEventArgs>(newSensor_ColorFrameReady);
            try
            {
                newSensor.Start();
            }
            catch (System.IO.IOException)
            {
                kinectSensorChooser1.AppConflictOccurred();
            }

        }

        BitmapSource depthImg, colorImg;

        int cHeight, cWidth;
        byte[] colorPixels = null;

        void newSensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
            {
                if (colorFrame == null) return;
                if (colorPixels == null)
                {
                    colorPixels = new byte[colorFrame.PixelDataLength];
                    cHeight = colorFrame.Height;
                    cWidth = colorFrame.Width;

                }
                colorFrame.CopyPixelDataTo(colorPixels);
                colorImg = colorFrame.ToBitmapSource();
            }
            writeColorFrame();
        }

        int height, width;
        short[] pixels = null;

        void newSensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        {
            using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
            {
                if (depthFrame == null) return;

                if (pixels == null)
                {
                    pixels = new short[depthFrame.PixelDataLength];
                    height = depthFrame.Height;
                    width = depthFrame.Width;
                }

                depthFrame.CopyPixelDataTo(pixels);
//                 depthImg = depthFrame.ToBitmapSource();
            }

            writeDepthFrame();

        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            fnCloseVideo();
        }

        void StopKinect(KinectSensor sensor)
        {
            if (sensor != null)
            {
                sensor.Stop();
                sensor.AudioSource.Stop();
                fnCloseVideo();
            }
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            using (StreamWriter writer = new StreamWriter("depthdata.txt"))
            {
                int idx = 0;
                for (int j = 0; j < height; ++j)
                {
                    for (int i = 0; i < width; ++i, ++idx)
                        writer.Write("\t{0:0}", pixels[idx]);
                    writer.WriteLine();
                }
            }
            depthImg.Save("depthImg.png", ImageFormat.Png);
        }
    }
}
